package com.bailian.snails.config;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.annotation.Configuration;
import org.yaml.snakeyaml.Yaml;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 * @author gaoxu
 * date: Created on 2021/8/27 下午1:51
 */
@Configuration
@Slf4j
public class DynamicRouteNacosConfiguration {

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @Autowired
    private NacosProperties nacosProperties;

    @PostConstruct
    public void initRoute() {
        try {
            Properties properties = new Properties();
            properties.put("serverAddr", nacosProperties.getServerAddr());
            properties.put("namespace", nacosProperties.getNamespace());
            ConfigService configService = NacosFactory.createConfigService(properties);
            String content = configService.getConfig(nacosProperties.getDataId(), nacosProperties.getGroup(), nacosProperties.getTimeout());
            log.info("初始化网关路由开始.........");
            updateRoute(content);
            log.info("初始化网关路由完成..........");

            //开户监听，实现动态监听nacos配置文件
            configService.addListener(nacosProperties.getDataId(), nacosProperties.getGroup(), new Listener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    log.info("更新网关路由开始");
                    updateRoute(configInfo);
                    log.info("更新网关路由完成");
                }

                @Override
                public Executor getExecutor() {
                    return null;
                }
            });
        } catch (NacosException e) {
            log.error("加载路由出错：{}", e.getErrMsg());
        }
    }

    /**
     * @param content
     * @return void
     * @description: 更新路由
     **/
    private void updateRoute(String content) {
        Yaml yaml = new Yaml();
        GatewayRouteList gatewayRouteList = yaml.loadAs(content, GatewayRouteList.class);
        gatewayRouteList.getRoutes().forEach(route -> {
            log.info("加载路由：{},{}", route.getId(), route);
            routeDefinitionWriter.save(Mono.just(route)).subscribe();
        });
    }
}